﻿using Microsoft.EntityFrameworkCore;
using System;
using System.Linq;
using ZSZ.Application.IService;
using ZSZ.Core.Entities;
using ZSZ.DTO;
using ZSZ.EntityFramework;

namespace ZSZ.Application.Service
{
    public class HouseAppointmentService : Repository<HouseAppointmentEntity>, IHouseAppointmentService
    {
        public long AddNew(long? userId, string name, string phoneNum, long houseId, DateTime visitDate)
        {
            var houseApp = new HouseAppointmentEntity
            {
                HouseId = houseId,
                Name = name,
                PhoneNum = phoneNum,
                Status = "未处理",
                UserId = userId,
                VisitDate = visitDate
            };

            SaveOrUpdate(houseApp,true);
            return houseApp.Id;
        }

        public bool Follow(long adminUserId, long houseAppointmentId)
        {
            var app = GetOneById(houseAppointmentId);
            if (app == null)
            {
                throw new ArgumentException("不存在的订单id");
            }
            //FollowAdminUserId不为null，说明要么是自己已经抢过，要么是已经早早的
            //被别人抢了
            if (app.FollowAdminUserId != null)
            {
                return app.FollowAdminUserId == adminUserId;
                /*
                if(app.FollowAdminUserId==adminUserId)
                {
                    return true;
                }
                else
                {
                    return false;
                }*/
            }
            //如果/FollowAdminUserId为null，说明有抢的机会
            app.FollowAdminUserId = adminUserId;
            try
            {
                SaveOrUpdate(app,false);
                return true;
            }//如果抛出DbUpdateConcurrencyException说明抢单失败（乐观锁）
            catch (DbUpdateConcurrencyException)
            {
                return false;
            }
        }

        private HouseAppointmentDTO ToDTO(HouseAppointmentEntity houseApp)
        {
            var dto = new HouseAppointmentDTO
            {
                CommunityName = houseApp.House.Community.Name,
                CreateDateTime = houseApp.CreateDateTime,
                FollowAdminUserId = houseApp.FollowAdminUserId
            };
            if (houseApp.FollowAdminUser!=null)
            {
                dto.FollowAdminUserName = houseApp.FollowAdminUser.Name;
            }
            dto.FollowDateTime = houseApp.FollowDateTime;
            dto.HouseId = houseApp.HouseId;
            dto.Id = houseApp.Id;
            dto.Name = houseApp.Name;
            dto.PhoneNum = houseApp.PhoneNum;
            dto.RegionName = houseApp.House.Community.Region.Name;
            dto.Status = houseApp.Status;
            dto.UserId = houseApp.UserId;
            dto.VisitDate = houseApp.VisitDate;
            dto.HouseAddress = houseApp.House.Address;
            return dto;
        }

        public HouseAppointmentDTO GetById(long id)
        {
            var houseApp = GetAllDataEntity().Include(a => a.House)
                //Include("House.Community")
                .Include(nameof(HouseAppointmentEntity.House) + "." + nameof(HouseEntity.Community))
                .Include(a => a.FollowAdminUser)
                //Include("House.Community.Region")
                .Include(nameof(HouseAppointmentEntity.House) + "." + nameof(HouseEntity.Community) + "." + nameof(CommunityEntity.Region))
                .AsNoTracking().SingleOrDefault(a => a.Id == id);
            if (houseApp == null)
            {
                return null;
            }
            return ToDTO(houseApp);
        }

        public HouseAppointmentDTO[] GetPagedData(long cityId, string status, 
            int pageSize, int currentIndex)
        {
            var apps = GetAllDataEntity().Include(a => a.House)
                .Include(nameof(HouseAppointmentEntity.House) + "." + nameof(HouseEntity.Community))
                .Include(a => a.FollowAdminUser)
                .Include(nameof(HouseAppointmentEntity.House) + "." + nameof(HouseEntity.Community) + "." + nameof(CommunityEntity.Region))
                .AsNoTracking()
                .Where(a => a.House.Community.Region.CityId == cityId && a.Status == status)
                .OrderByDescending(a => a.CreateDateTime)   //Skip之前一定要调用OrderBy
                .Skip(currentIndex).Take(pageSize);
            return apps.ToList().Select(a => ToDTO(a)).ToArray();
        }

        public long GetTotalCount(long cityId, string status)
        {
            var count = GetAllDataEntity()
                //Where(a => a.House.Community.Region.CityId == cityId && a.Status == status).LongCount()
                .LongCount(a => a.House.Community.Region.CityId == cityId && a.Status == status);
            return count;
        }

        public HouseAppointmentService(ZSZDbContext context) : base(context)
        {
        }
    }
}
